package utils.encrypt;
import java.security.SecureRandom;
import java.util.*;

/**
 * 密码生成器
 * @author ChenYuan
 */
public class PasswordGenerator {

    private static final SecureRandom RANDOM = new SecureRandom();
    private static final boolean INCLUDE_CHAR_LOWER = true;
    private static final boolean INCLUDE_CHAR_UPPER = true;
    private static final boolean INCLUDE_NUMBER = true;
    private static final boolean INCLUDE_OTHER_CHAR = true;

    private static final String CHAR_LOWER = "abcdefghijklmnopqrstuvwxyz";
    private static final String CHAR_UPPER = CHAR_LOWER.toUpperCase();
    private static final String NUMBER = "0123456789";
    private static final String OTHER_CHAR = "!@#$%^&*()_+-=[]{}|;':\",.<>?/";
    //private static final String PASSWORD_ALLOW_BASE = CHAR_LOWER + CHAR_UPPER + NUMBER + OTHER_CHAR;


    public static void main(String[] args) {
        System.out.println(generateSecurePassword(10));
    }


    /**
     * 生成一个安全性高的密码。
     *
     * @param length 密码长度
     * @return 生成的密码
     */
    public static String generateSecurePassword(int length) {
        if (length < 1) {
            throw new IllegalArgumentException("Length must be at least 1");
        }

        StringBuilder password = new StringBuilder(length);
        List<String> passwordAry = PasswordGenerator.getPasswordAllowAry();

        if (passwordAry.isEmpty()){
            return "12345678";
        }

        int aryIndex, characterIndex;
        String passwordCharacters;
        for (int i = 0; i < length; i++) {
            aryIndex = RANDOM.nextInt(passwordAry.size());
            passwordCharacters = passwordAry.get(aryIndex);
            characterIndex = RANDOM.nextInt(passwordCharacters.length());
            password.append(passwordCharacters.charAt(characterIndex));
        }

        return password.toString();
    }

    public static List<String> getPasswordAllowAry() {
        ArrayList<String> allowAry = new ArrayList<>();

        if (INCLUDE_CHAR_LOWER) {
            allowAry.add(CHAR_LOWER);
        }
        if (INCLUDE_CHAR_UPPER) {
            allowAry.add(CHAR_UPPER);
        }
        if (INCLUDE_NUMBER) {
            allowAry.add(NUMBER);
        }
        if (INCLUDE_OTHER_CHAR) {
            allowAry.add(OTHER_CHAR);
        }

        return allowAry;
    }
}

